/*
 * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @Date: 2024-07-28 09:06:15
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2024-07-29 20:18:00
 * @FilePath: /hw/110/Consumer_Productor/main.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "Thread.hpp"
#include <iostream>
#include "RingQueue.hpp"
#include"Task.hpp"
#include <string>
#include <unistd.h>
#include <vector>
#include <ctime>

using namespace std;
using namespace ThreadModule;

int a = 10;

using ringqueue_t = RingQueue<Task>;
void Consumer(ringqueue_t &rq, string name)
{
    while (1)
    {
        int cnt;
        sleep(1);
        Task t;
        //获取任务
        rq.Pop(&t);
        // cout << "Consumer consume data : " << cnt << "     [" << name << "]" << endl;
        cout << "Consumer : "  << "[" << name << "]" << endl;
        //处理任务
        t();

    }
}
void Productor(ringqueue_t &rq, std::string name)
{
    srand(time(nullptr) ^ pthread_self());
    //int cnt = 10;
    while (true)
    {
        // 获取任务
        // 生产任务
        rq.Enqueue(Download);
        std::cout << "Productor : " << "[" << name << "]" << std::endl;
        // cnt--;
    }
}
void InitComm(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq,
              func_t<ringqueue_t> func, const string &who)
{
    for (int i = 0; i < num; i++)
    {
        std::string name = "thread-" + std::to_string(i + 1) + "-" + who;
        threads->emplace_back(func, rq, name);
        //错误语句
        //threads->back().Start();  
        //因为主线程一直在执行，并且也一直在创建新线程，她的back()按理说是，新线程的后面，结果因为创建新线程，他的back就是新线程了
    }
}
void InitConsumer(vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    InitComm(threads, num, rq, Consumer, "consumer");
}
void InitProductor(vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    InitComm(threads, num, rq, Productor, "productor");
}
void WaitThread(vector<Thread<ringqueue_t>> &threads)
{

    for (auto &thread : threads)
    {
        thread.Join();
    }
}
void ALLstart(vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        cout << "start : " << thread.name() << endl;
        thread.Start();
        
    }
}
int main()
{
    ringqueue_t *rq = new ringqueue_t(10);
    vector<Thread<ringqueue_t>> threads;
    InitConsumer(&threads, 1, *rq);
    InitProductor(&threads, 1, *rq);
    ALLstart(threads);
    WaitThread(threads);

    return 0;
}

